#ifndef _FENGINE_CAMERA
#define _FENGINE_CAMERA

#include "AABB.h"

namespace FEngine
{
	class Node;
	
	/**
	 * Represent the point of view of the scene.
	 */
	class Camera
	{

		public:

			static enum FrustumPlane
			{
				PLANE_NEAR = 0,
				PLANE_FAR,
				PLANE_LEFT,
				PLANE_RIGHT,
				PLANE_TOP,
				PLANE_BOTTOM,
			};

			/**
			 * Constructor.
			 */
			Camera();
			~Camera();


		public:
			
			/**
			 * Set the position of the camera.
			 * @param _pos Vector3 containing the position of the camera.
			 */
			void setPosition(const Vector3& _pos);
			
			/**
			 * Return the position of the camera.
			 * @return Vector3 containing the position of the camera.
			 */
			Vector3 getPosition() const;
			
			/**
			 * Set the Look At point of the camera.
			 * @param _pos Vector3 containing the Look At point of the camera.
			 */
			void lookAt(const Vector3& _pos);
			
			/**
			 * Return the Look At point of the camera.
			 * @return Vector3 containing the Look At point of the camera.
			 */
			Vector3 getLookAt() const;
			
			/**
			 * Set the near distance limit of the camera.
			 * @param _view near distance view.
			 */
			void setNearDistanceView(float _view);
			
			/**
			 * Get the near distance limit of the camera.
			 * @return The near distance view.
			 */
			float getNearDistanceView() const;
			
			/**
			 * Set the far distance limit of the camera.
			 * @param _view far distance view.
			 */
			void setFarDistanceView(float _view);
			
			/**
			 * Get the far distance limit of the camera.
			 * @return The far distance view.
			 */
			float getFarDistanceView() const;

			/**
			 * Test is the given AABB is in the camera view.
			 * @param _box AABB box to test.
			 * @return True if the AABB is in the camera view.
			 */
			NodeVisibility isVisible(AABB* _box, bool _useCustomMaxView = false);
			
			/**
			 * Get the View matrix of the camera.
			 * @return The View matrix of the camera.
			 */
			Matrix4 _getMatrixView() const;
			
			/**
			 * Get the Projection matrix of the camera.
			 * @return The Projection matrix of the camera.
			 */
			Matrix4 _getMatrixProjection() const;


			void _setCustomFrustumCulling(float _maxViewDist);
			NodeVisibility _customIsVisible(AABB* _box);

			
		private:

			Vector3			mPosition;
			Vector3			mLookAt;
			float			mNearViewDist;
			float			mFarViewDist;

			Matrix4			mViewMatrix;
			Matrix4			mProjectionMatrix;
			
			Plane			mFrustumPlanes[6];
			Plane			mCustomFrustumPlanes[6];
			
			void _calculateViewMatrix();
			void _calculateProjMatrix();
			
			void _calculateFrustumPlane();
	};
}

#endif
